package system

import (
	"gin-admin/common/dto/response"
	"gin-admin/core"
	"gin-admin/model"
	"gin-admin/repo"
	serviceRequest "gin-admin/service/dto/request"

	"gorm.io/gorm"
)

type RoleMenuService struct {
	RoleRepository *repo.Repository[model.Role]
	MenuRepository *repo.Repository[model.Menu]
	Repository     *repo.Repository[model.RoleMenu]
}

func NewRoleMenuServiceApp(
	roleRepository *repo.Repository[model.Role],
	menuRepository *repo.Repository[model.Menu],
	repository *repo.Repository[model.RoleMenu],
) *RoleMenuService {
	return &RoleMenuService{
		RoleRepository: roleRepository,
		MenuRepository: menuRepository,
		Repository:     repository,
	}
}

func (rms *RoleMenuService) CreateRoleMenuInfoService(requestData *serviceRequest.CreateRoleMenuRequest) (bool, *response.ServiceError) {
	if err := rms.checkRoleExistsWithRoleId(requestData.RoleID); err != nil {
		return false, err
	}
	existsMenus, err := rms.MenuRepository.CheckDataBatchExistsByIds(requestData.Menus)
	if err != nil {
		return false, err
	}
	for _, menuId := range requestData.Menus {
		if !existsMenus[menuId] {
			continue
		}
		condition := map[string]interface{}{
			"role_id": requestData.RoleID,
			"menu_id": menuId,
		}
		roleMenu := model.RoleMenu{
			RoleID: requestData.RoleID,
			MenuID: menuId,
		}
		if err := core.UseTransactionWith(rms.Repository.DB, func(tx *gorm.DB) *response.ServiceError {
			if err := rms.Repository.GenericCreateRelationshipDataWithTransaction(tx, &roleMenu, condition, roleExistsHandler); err != nil {
				return err
			}
			return nil
		}); err != nil {
			return false, err
		}
	}
	return true, nil
}

func (rms *RoleMenuService) DeleteRoleMenuInfoService(id string) (bool, *response.ServiceError) {
	return rms.Repository.GenericLogicDeleteById(id, "", roleNotFoundHandler)
}

func (rms *RoleMenuService) ModifyRoleMenuInfoService() (bool, *response.ServiceError) {
	return true, nil
}

func (rms *RoleMenuService) GetRoleMenuInfoService() (bool, *response.ServiceError) {
	return true, nil
}

func (rms *RoleMenuService) GetRoleMenuListService() (bool, *response.ServiceError) {
	return true, nil
}

func (rms *RoleMenuService) GetRoleMenuPageService() (bool, *response.ServiceError) {
	return true, nil
}

func (rms *RoleMenuService) roleMenuNotFoundHandler() *response.ServiceError {
	return response.WrapError(
		response.RoleMenuNotFoundCode,
		response.GetStatusCode(response.RoleMenuNotFoundCode).Message,
	)
}
func (rms *RoleMenuService) checkRoleExistsWithRoleId(roleId string) *response.ServiceError {
	condition := map[string]interface{}{
		"id": roleId,
	}
	exists, err := rms.RoleRepository.CheckDataExistsByCondition(condition, "")
	if err != nil {
		return err
	}
	if !exists {
		return rms.roleMenuNotFoundHandler()
	}
	return nil
}
